#!/usr/bin/python
#wxclam.py
import wx,pyclamav
import sys,os
import pdb,time
VERSION = "0.1"
class cls_frame(wx.Frame):
	def __init__(self,parent,id,title):
		wx.Frame.__init__(self,parent,id,title,wx.DefaultPosition,wx.Size(640,480))
		frame = wx.Frame(None,-1,'wxclam')
		frame.SetToolTip(wx.ToolTip('wxclam'))
		frame.SetSize(wx.Size(640,480))
		vbox = wx.BoxSizer(wx.VERTICAL)
		self.statusbar = self.CreateStatusBar()
		#handle menu
		menubar = wx.MenuBar()
		mn_scan = wx.Menu()
		mn_scan_file = wx.MenuItem(mn_scan,102,'&File...\tCtrl+F','scan file')
		mn_scan_file.SetBitmap(wx.Image('img/onefile.png',wx.BITMAP_TYPE_PNG).ConvertToBitmap())
		mn_scan.AppendItem(mn_scan_file)
		mn_scan_fold = wx.MenuItem(mn_scan,103,'F&old...\tCtrl+O','scan fold')
		mn_scan_fold.SetBitmap(wx.Image('img/onefold.png',wx.BITMAP_TYPE_PNG).ConvertToBitmap())
		mn_scan.AppendItem(mn_scan_fold)
		mn_scan.AppendSeparator()
		mn_scan.Append(101,'E&xit','Exit system')
		mn_tools = wx.Menu()
		mn_tools.Append(201,"Op&tion","options")
		mn_help = wx.Menu()
		mn_help.Append(301,'&About','system info')
		menubar.Append(mn_scan,'&Scan')
		menubar.Append(mn_tools,'&Tools')
		menubar.Append(mn_help,'&Help')
		self.SetMenuBar(menubar)
		#handle toolbar
		toolbar = wx.ToolBar(self,-1,style = wx.TB_HORIZONTAL |	wx.NO_BORDER)
		toolbar.AddSimpleTool(11,wx.Image('img/onefile.png',wx.BITMAP_TYPE_PNG).ConvertToBitmap(),'scan file','')
		toolbar.AddSimpleTool(12,wx.Image('img/onefold.png',wx.BITMAP_TYPE_PNG).ConvertToBitmap(),'scan fold','')
		toolbar.AddSimpleTool(13,wx.Image('img/all.png',wx.BITMAP_TYPE_PNG).ConvertToBitmap(),'scan all','')
		toolbar.AddSeparator()
		toolbar.AddSimpleTool(14,wx.Image('img/start.png',wx.BITMAP_TYPE_PNG).ConvertToBitmap(),'scan all','')
		toolbar.AddSimpleTool(15,wx.Image('img/pause.png',wx.BITMAP_TYPE_PNG).ConvertToBitmap(),'scan all','')
		toolbar.AddSimpleTool(16,wx.Image('img/stop.png',wx.BITMAP_TYPE_PNG).ConvertToBitmap(),'scan all','')
		toolbar.Realize()
		vbox.Add(toolbar,0,border = 5)
		#handle scan
		staticbox_scan = wx.StaticBox(self,-1,'Scan',(-1,-1),size = (630,20))
		sb_scan = wx.StaticBoxSizer(staticbox_scan)
		self.lb_curr = wx.StaticText(self,-1,'Current file:')
		sb_scan.Add(self.lb_curr,0,wx.ALL)
		vbox.Add(sb_scan,1,wx.EXPAND|wx.ALL)
		#handle virus list
		self.listctrl_virus = wx.ListCtrl(self,-1,style = wx.LC_REPORT)
		self.listctrl_virus.InsertColumn(0,'File')
		self.listctrl_virus.InsertColumn(1,'Status')
		self.listctrl_virus.InsertColumn(2,'Detail')
		self.listctrl_virus.SetColumnWidth(0,200)
		self.listctrl_virus.SetColumnWidth(1,200)
		self.listctrl_virus.SetColumnWidth(2,300)
		vbox.Add(self.listctrl_virus,1,wx.EXPAND|wx.ALL)
		#handle scan info
		staticbox_info = wx.StaticBox(self,-1,'Info',(5,5),size = (640,100))
		sb_info = wx.StaticBoxSizer(staticbox_info)
		bs_vbox = wx.BoxSizer(wx.VERTICAL)
		self.lb_total = wx.StaticText(self,-1,"total files:")
		self.lb_scaned = wx.StaticText(self,-1,"scaned files:")
		self.lb_virus = wx.StaticText(self,-1,'scaned virus:')
		bs_vbox.Add(self.lb_total,0,wx.ALL)
		bs_vbox.Add(self.lb_scaned,0,wx.ALL)
		bs_vbox.Add(self.lb_virus,0,wx.ALL)
		sb_info.Add(bs_vbox,0,wx.ALL)
		vbox.Add(sb_info,1,wx.EXPAND | wx.ALL,3)
		#handle progress
		pnl_progress = wx.Panel(self,-1,wx.Point(0,0),wx.Size(640,30))
		self.gauge_progress = wx.Gauge(pnl_progress,-1,50,size = (640,20))
		self.gauge_progress.SetRange(100)
		vbox.Add(pnl_progress,1,wx.EXPAND | wx.ALL,3)
		self.SetSizer(vbox)
		self.Layout()
		#handle other
		self.timer = wx.Timer(self,1)
		self.file_count = 0
		self.file_curr = 0
		frame.Center()
		#handle event
		self.Bind(wx.EVT_MENU,self.on_quit,id = 101)
		self.Bind(wx.EVT_MENU,self.on_about,id = 301)
		self.Bind(wx.EVT_MENU,self.on_scan_file,id = 102)
		self.Bind(wx.EVT_TOOL,self.on_scan_file,id = 11)
		self.Bind(wx.EVT_MENU,self.on_scan_fold,id = 103)
		self.Bind(wx.EVT_TOOL,self.on_scan_fold,id = 12)
		self.Bind(wx.EVT_TIMER,self.on_timer,self.timer)
		self.listctrl_virus.Bind(wx.EVT_CONTEXT_MENU,self.on_list_ctrl_virus_right_down)
	def on_quit(self,event):
		self.Close()
		sys.exit()
	def on_about(self,event):
		str_ver = """
wxClam ver             : %s
Clamav ver       : %s
Libclamav ver          : %s
Libclamav signature ver: %s""" % \
			   (VERSION,
			    pyclamav.version(),
			    pyclamav.get_version(),
			    pyclamav.get_numsig())
		msg_dlg = wx.MessageDialog(self,str_ver,"about",wx.OK)
		msg_dlg.ShowModal()
		msg_dlg.Destroy()
	def on_scan_file(self,event):
		dlg = wx.FileDialog(self,"choose a file",os.getcwd(),"","*.*",wx.OPEN)
		path = str()
		if dlg.ShowModal() == wx.ID_OK:
			path = dlg.GetPath()
		dlg.Destroy()
		if len(path) == 0:
			return
		self.lb_curr.SetLabel("Current File:%s" % path)
		self.listctrl_virus.DeleteAllItems()
		obj_scan = scanvirus.cls_scan()
		dct_result = obj_scan.scan_file(path)
		#pdb.set_trace()
		self.listctrl_virus.InsertStringItem(0,path)
		self.listctrl_virus.SetStringItem(0,1,dct_result['is_virus'])
		self.listctrl_virus.SetStringItem(0,2,dct_result['detail'])
		self.gauge_progress.SetValue(100)
		msg_dlg = wx.MessageDialog(self,"scan finished!","info",wx.OK)
		msg_dlg.ShowModal()
		msg_dlg.Destroy()
	def on_scan_fold(self,event):
		dlg = wx.DirDialog(self,"choose a directory",style=wx.DD_DEFAULT_STYLE | wx.DD_NEW_DIR_BUTTON)
		path = str()
		if dlg.ShowModal() == wx.ID_OK:
			path = dlg.GetPath()
		dlg.Destroy()
		if len(path) == 0:
			return
		self.lb_total.SetLabel("Current File:%s" % path)
		self.listctrl_virus.DeleteAllItems()
		self.obj_scan = scanvirus.cls_scan()
		self.obj_scan.list_fold(path)
		self.lst_files = self.obj_scan.lst_path
		self.file_count = len(self.lst_files)
		self.n_virus = 0
		self.file_curr = 0
		self.n_insert = 0
		self.lb_total.SetLabel("total files:%d" % self.file_count)
		self.gauge_progress.SetRange(100)
		self.gauge_progress.SetValue(0)
		self.timer.Start(10)
		'''
		for i in lst_files:
			#pdb.set_trace()
			self.lb_curr.SetLabel("Current File:%s" % i)
			dct_result = obj_scan.scan_file(i)
			if not cmp(dct_result['is_virus'],'OK') == 0:
				self.listctrl_virus.InsertStringItem(n,i)
				self.listctrl_virus.SetStringItem(n,1,dct_result['is_virus'])
				self.listctrl_virus.SetStringItem(n,2,dct_result['detail'])
			n += 1
			self.lb_scaned.SetLabel("scaned files:%d" % n)
			self.lb_virus.SetLabel("scaned virus:%d" % n_virus)
			self.gauge_progress.SetValue(n)
		msg_dlg = wx.MessageDialog(self,"scan finished!","info",wx.OK)
		msg_dlg.ShowModal()
		msg_dlg.Destroy()
		'''
	def on_timer(self,event):
		#pdb.set_trace()
		n_progress = (self.file_curr + 1) * (100.0/self.file_count)
		self.gauge_progress.SetValue(n_progress)
		if self.file_curr >= self.file_count:
			msg_dlg = wx.MessageDialog(self,"scan finished!","info",wx.OK)
			msg_dlg.ShowModal()
			msg_dlg.Destroy()
			self.timer.Stop()
			return
		#pdb.set_trace()
		i = self.lst_files[self.file_curr]
		self.lb_curr.SetLabel("Current File:%s" % i)
		dct_result = self.obj_scan.scan_file(i)
		if not cmp(dct_result['is_virus'],'OK') == 0:
			self.listctrl_virus.InsertStringItem(self.n_insert,i)
			self.listctrl_virus.SetStringItem(self.n_insert,1,dct_result['is_virus'])
			self.listctrl_virus.SetStringItem(self.n_insert,2,dct_result['detail'])
		self.lb_scaned.SetLabel("scaned files:%d" % (self.file_curr + 1))
		self.lb_virus.SetLabel("scaned virus:%d" % self.n_virus)
		#pdb.set_trace()
		self.file_curr += 1
	def on_list_ctrl_virus_right_down(self,event):
		if self.listctrl_virus.GetItemCount() <= 0:
			return
		if self.listctrl_virus.GetSelectedItemCount() <= 0:
			return
		pos = event.GetPosition()
		pos = self.listctrl_virus.ScreenToClient(pos)
		self.n_sel_itm = -1
		#pdb.set_trace()
		while 1:
			self.n_sel_itm = self.listctrl_virus.GetNextItem(self.n_sel_itm,wx.LIST_NEXT_ALL,wx.LIST_STATE_SELECTED)
			if (self.n_sel_itm != -1):
				break
		print self.n_sel_itm
		print self.listctrl_virus.GetItemText(self.n_sel_itm)
		global g_sel_file 
		g_sel_file = self.listctrl_virus.GetItemText(self.n_sel_itm)
		pop_menu = cls_virus_popup_menu(self)
		self.listctrl_virus.PopupMenu(pop_menu,pos)
		pop_menu.Destroy()
class cls_win(wx.App):
	def __init__(self):
		self.app = wx.App()
		self.frame = cls_frame(None,-1,"wxclam")
	def show(self):
		self.frame.Show()
		self.app.MainLoop()
class cls_virus_popup_menu(wx.Menu):
	def __init__(self,win_name):
		wx.Menu.__init__(self)
		self.win_name = win_name
		itm = wx.MenuItem(self,801,"&Delete")
		self.AppendItem(itm)
		self.Bind(wx.EVT_MENU,self.on_delete,itm)
		itm = wx.MenuItem(self,802,"&Quarantine")
		self.AppendItem(itm)
		self.Bind(wx.EVT_MENU,self.on_quarantine,itm)
		self.Enable(802,False)
	def on_delete(self,event):
		#pdb.set_trace()
		global g_sel_file
		print 'delete %s ' % g_sel_file
		try:
			os.remove(g_sel_file)
		except Exception,e:
			print 'remove file faild.[%s]' % str(e)
			return
		self.win_name.listctrl_virus.DeleteItem(self.win_name.n_sel_itm)
		return
	def on_quarantine(self,event):
		print 'quarantine'
if __name__ == '__main__':
	try:
		import scanvirus
	except ImportError,e:
		print 'import module faild.[%s]' % str(e)
		sys.exit()
	g_sel_file = ''
	obj_win = cls_win()
	obj_win.show()
